import random
import sys
import time
from constants import *

import pygame


class Snake:
    """
        # 0, 90, 180, 270
        # 0, 1 ,  2 , 3
        #下, 右 , 上 , 左
    """

    def __init__(self, x, y):
        self.direction = pygame.K_RIGHT  # 右
        self.score = 0
        self.cross_wall_enable = True

        self.snake_body = [
            pygame.Rect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE)
        ]

        # 存储最新的连续两次有效方向按键，提高响应速度
        self.new_direction_queue = []

        snake_head = pygame.image.load("img/head-red.png")
        # 缩放
        self.snake_head_image = pygame.transform.scale(snake_head, (BLOCK_SIZE, BLOCK_SIZE))
        self.rotated_snake_head = self.rotate_snake_head()  # 旋转蛇头
        for _ in range(3):
            self.grow()

    def rotate_snake_head(self):
        return pygame.transform.rotate(self.snake_head_image, DIRECTION_HEAD_ANGLE[self.direction])

    def draw(self, screen):
        # 绘制身体
        for node in self.snake_body[1:]:
            # 绘制矩形 (x, y, w, h)
            pygame.draw.rect(screen, COLOR_WHITE, node, border_radius=3)

        head_rect: pygame.Rect = self.snake_body[0]  # 取出蛇头
        # 绘制蛇头
        screen.blit(self.rotated_snake_head, (head_rect.x, head_rect.y))

    def move(self):
        """
        让蛇根据当前方向进行移动（移动一格） prompt
        """
        # 把蛇头往前进的方向复制一份
        new_node = self.snake_body[0].copy()
        new_move = DIRECTION_MOVE[self.direction]  # 取出对应方向的x, y变化格子数
        new_node.x += (new_move[0] * BLOCK_SIZE)
        new_node.y += (new_move[1] * BLOCK_SIZE)

        if self.cross_wall_enable:
            # 如果超出了边缘进行瞬移
            if new_node.x >= SCREEN_WIDTH:
                new_node.x -= SCREEN_WIDTH
            elif new_node.x < 0:
                new_node.x += SCREEN_WIDTH

            if new_node.y >= SCREEN_HEIGHT:
                new_node.y -= SCREEN_HEIGHT
            elif new_node.y < 0:
                new_node.y += SCREEN_HEIGHT

        # 把新的头放到最前边
        self.snake_body.insert(0, new_node)

        # 把蛇尾移除掉
        self.snake_body.pop()  # 默认删除末尾数

    def is_direction_enable(self, event_key, cur_direction=None):
        # 判断event_key是否是合法的按键，上下左右
        if event_key not in DIRECTION_MOVE.keys():
            return False
        if cur_direction is None:
            cur_direction = self.direction
            # 蛇不能直接原地掉头
        # 不能左右掉头
        LR = (pygame.K_LEFT, pygame.K_RIGHT)
        if event_key in LR and cur_direction in LR:
            return False
        # 不能上下掉头
        UD = (pygame.K_UP, pygame.K_DOWN)
        if event_key in UD and cur_direction in UD:
            return False

        return True

    def update_direction(self, event_key):
        self.direction = event_key
        self.rotated_snake_head = self.rotate_snake_head()  # 旋转蛇头

    def grow(self):

        # 蛇尾复制一份
        new_node = self.snake_body[-1].copy()
        # 添加到尾部
        self.snake_body.append(new_node)
        # 加一分
        self.score += 1

    def handle_key_event(self, event):
        """
        处理按键事件
        记录最新的两个方向按键，提高响应速度
        这两个方向键必须是合法的方向键（即不能掉头，不能是相同方向）
        :param event: pygame.event
        """

        if len(self.new_direction_queue) == 0 and self.is_direction_enable(event.key):
            self.new_direction_queue.append(event.key)
        elif len(self.new_direction_queue) > 0 and self.is_direction_enable(event.key, self.new_direction_queue[0]):
            if len(self.new_direction_queue) == 1:
                self.new_direction_queue.append(event.key)
            else:
                self.new_direction_queue[1] = event.key

    def get_current_direction(self):
        """
        获取最新的方向
        """
        if len(self.new_direction_queue) > 0:
            return self.new_direction_queue.pop(0)

        return None


class Food:
    """
    食物
    """

    def __init__(self, pos):
        x, y = pos
        # x = random.randint(0, SCREEN_WIDTH // BLOCK_SIZE - 1)  # 0, 1, 2, ... 31  (640)
        # y = random.randint(0, SCREEN_HEIGHT // BLOCK_SIZE - 1)  # 0, 1, 2, ... 23 (480)
        self.rect = pygame.Rect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE)

    def draw(self, screen):
        pygame.draw.rect(
            screen, (0, 0, 255),  # 颜色
            self.rect,  # 位置、大小的矩形
            border_radius=3
        )
